/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ca.usask.cs.decisiontree.DOTHandler;

import ca.usask.cs.Startup.Main;
import ca.usask.cs.decisiontree.*;
import ca.usask.cs.decisiontree.api.Edge;
import ca.usask.cs.decisiontree.api.IntermediateTreeNode;
import ca.usask.cs.decisiontree.api.TreeNode;

import java.util.ArrayList;
import java.util.Iterator;


/**
 *
 * @author tonyleung
 */
public class DOTController
{
    private Main mainController;
    private ArrayList<Double> timeList;
    private ArrayList<TreeNode> nodeList;
    private ArrayList<Edge> edgeList;
    private WriteDOT write;
    
    public DOTController(Main theMainController)
    {
    	initialDOT(theMainController);
    }
    
    private void initialDOT(Main theMainController){
    	 this.mainController = theMainController;
         this.write = new WriteDOT();
         this.timeList = new ArrayList<Double>();
         this.nodeList = new ArrayList<TreeNode>();
         this.edgeList = new ArrayList<Edge>();
    }

    /**
     * writes the xml file specified by the constructor
     */
    public void write(String theFileName)
    {
        DecisionTree tree = this.mainController.getTreeSturcture().getDecisionTree();
        String fileName = theFileName;
        if(tree != null || tree != null)
        {
            this.populateStack(tree.getRootNode());
            write.write(fileName, tree, nodeList, edgeList, timeList);
        }
    }  

    /**
     * recursive function that uses dfs to iterate through the tree.
     *      it will add each node, edge and time into its corresponding list
     *      it ensures that no duplicate times are in the list
     * @param curNode
     */
    private void populateStack(TreeNode curNode)
    {
        // add the curNode to the nodeList
        this.nodeList.add(curNode);
        //if the time of the curNode is not already in the time list, add to timeList
        if(!this.timeList.contains(curNode.getTime()))
        {
            this.timeList.add(curNode.getTime());
        }
        // if curNode is terminalNode then end
        if(curNode.getNodeType().equals("TerminalNode"))
        {
            return;
        }
        // if it is an intermediate treenode, grab its children
        // for each child add it to the edge list and recurse using its destination node
        else if(curNode.getNodeType().equals("ChanceNode")||curNode.getNodeType().equals("DecisionNode"))
        {
            IntermediateTreeNode curInterNode = (IntermediateTreeNode) curNode;
            Iterator<Edge> edgeIter = curInterNode.getChildEdgeList();

            while(edgeIter.hasNext())
            {
                Edge curEdge = edgeIter.next();
                this.edgeList.add(curEdge);
                this.populateStack(curEdge.getDestinationNode());
            }
        }
    }
  
}
